package main

import (
	"fmt"
	"net/http"
	"reflect"
	"strings"
)

func hello(w http.ResponseWriter, req *http.Request) {
	w.Write([]byte("Hello"))
}

func say(w http.ResponseWriter, req *http.Request) {
	w.Write([]byte("Hello say"))
}

type Handlers struct {
}

func (h *Handlers) ResAction(w http.ResponseWriter, req *http.Request) {
	fmt.Println("res")
	w.Write([]byte("res"))
}
func talk(w http.ResponseWriter, req *http.Request) {
	pathInfo := strings.Trim(req.URL.Path, "/")
	parts := strings.Split(pathInfo, "/")
	fmt.Println(strings.Join(parts, "|"))

	var action = ""
	if len(parts) > 1 {
		action = strings.Title(parts[1]) + "Action"
	}
	fmt.Println("action is:" + action)

	// 如果想根据action来确定处理的方法名 就必须有一个 methodByName 的操作
	// 可以用switch实现，也可以用 reflect.Value 的方法实现 此处选后者
	// 因此要先反射出一个包含以上处理方法的 value 即
	handle := &Handlers{}
	controller := reflect.ValueOf(handle) //由于Handlers的方法是绑定到指针上的，所以只能反射一个 &Handlers{} 否则此处反射一个 Handlers{} 也可以
	method := controller.MethodByName(action)

	//如果反射失败 方法不存在就不处理
	if method.IsValid() {
		r := reflect.ValueOf(req)
		wr := reflect.ValueOf(w)

		method.Call([]reflect.Value{wr, r})
	}
}

func main() {
	http.HandleFunc("/hello", hello)
	http.Handle("/say", http.HandlerFunc(say))      //做个强制类型转换
	http.Handle("/handle/", http.HandlerFunc(talk)) //适用url /handel/res /handel/rsa
	http.ListenAndServe(":8001", nil)
	select {}
}
